package org.linlinjava.litemall.admin.job;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.linlinjava.litemall.admin.beans.Constants;
import org.linlinjava.litemall.admin.beans.bo.GoodsItemBo;
import org.linlinjava.litemall.admin.util.DateUtil;
import org.linlinjava.litemall.core.notify.NoticeHelper;
import org.linlinjava.litemall.db.domain.*;
import org.linlinjava.litemall.db.service.*;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 卢米埃订阅工作
 *
 * @author yliyun
 * @description
 * @date 2022/09/14
 */
@Component
public class LumiereSubscribeJob implements Job {
    /**
     * 日志记录器
     */
    private final Log logger = LogFactory.getLog(SubscribeJob.class);

    /**
     * 卢米埃订阅用户服务
     */
    @Autowired
    private LumiereSubscribeUserService lumiereSubscribeUserService;

    /**
     * 卢米埃订阅服务
     */
    @Autowired
    private LumiereSubscribeService lumiereSubscribeService;

    /**
     * litemall商品服务
     */
    @Autowired
    private LitemallGoodsService litemallGoodsService;

    /**
     * 订单服务
     */
    @Autowired
    private LitemallOrderService orderService;
    /**
     * litemall货物产品服务
     */
    @Autowired
    private LitemallGoodsProductService litemallGoodsProductService;
    /**
     * 用户服务
     */
    @Autowired
    private LitemallUserService userService;
    /**
     * litemall地址服务
     */
    @Autowired
    private LitemallAddressService litemallAddressService;

    /**
     * 卢米埃订阅规则服务
     */
    @Autowired
    private LumiereSubscribeRuleService lumiereSubscribeRuleService;

    /**
     * 卢米埃订阅用户订单服务
     */
    @Autowired
    private LumiereSubscribeUserOrderService lumiereSubscribeUserOrderService;

    /**
     * 卢米埃subscirbe商品服务
     */
    @Autowired
    private LumiereSubscirbeGoodsService lumiereSubscirbeGoodsService;

    /**
     * litemall订货服务
     */
    @Autowired
    private LitemallOrderGoodsService litemallOrderGoodsService;

    @Autowired
    private LumiereSubscribeUserLogService lumiereSubscribeUserLogService;

    /**
     * litemall商品规范服务
     */
    @Autowired
    private LitemallGoodsSpecificationService litemallGoodsSpecificationService;

    @Autowired
    private NoticeHelper noticeHelper;

    /**
     * 提交订阅
     * 根据Lumiere_subscribe_user表对应的订阅配置，判断是否可以自动生成订单(定时任务每天一点执行)
     */
    //@Scheduled(cron = "0 0 1 * * ?")
    public void submitSubscribe() {
        logger.info("根据订阅自动生成订单");
        //获取当天日期 yyyy-MM-dd
        LocalDate today = LocalDate.now();
        //查询所有的user表中对应订阅设置中order_rule为1的user(订单的生成不需要确认)
        List<LumiereSubscribeUser> users = lumiereSubscribeUserService.queryAll();
        users.stream().forEach(item -> {
            Integer number= 0;
            LumiereSubscribeRule nowRule = lumiereSubscribeRuleService.queryByPrimaryKey(item.getRuleId());
            LumiereSubscribe lumiereSubscribe = lumiereSubscribeService.findById(item.getSubscribeId());
             logger.info("auto handle subscribe start, id is :" + item.getId());
            List<LocalDate> dates = new ArrayList<>();
            if(item.getGoodsId() != null){
                LitemallGoods goods = litemallGoodsService.findById(item.getGoodsId());

                //查询订阅对应的rule
                LocalDate startDate = item.getStartTime().toLocalDate();
                LocalDate endDate = item.getEndTime().toLocalDate();
                Integer dayL = item.getDeliveryDays().length;
                Integer dayD = item.getDeliveryDates().length;
                //判断订阅方式  查看 rule是 weektimes/monthtimes/yeartimes 哪一个为不为空，则按照哪种规则
                if(!( dayL== 0 && dayD == 0)){
                    if(nowRule.getWeekTimes() != null && nowRule.getWeekTimes() != 0){
                        dates = DateUtil.getMeetDayOfWeekLocalDates(startDate,endDate,item.getDeliveryDays ());
                    }else if(nowRule.getMonthTimes() != null && nowRule.getMonthTimes() != 0){
                        dates = DateUtil.getMeetDayOfMonthLocalDates(startDate,endDate,item.getDeliveryDays());
                    }else if(nowRule.getYearTimes() != null && nowRule.getYearTimes() != 0){
                        dates = DateUtil.getMeetDayOfYearDates(item.getDeliveryDates());
                    }else{
                        dates = DateUtil.getMeetDaysOfDays(startDate,endDate);
                    }
                }else{
                    if(item.getStartTime().minusDays(1).toLocalDate().isBefore(LocalDate.now()) && item.getEndTime().plusDays(1).toLocalDate().isAfter(LocalDate.now())){
                        dates.add(LocalDate.now());
                    }
                }

                if(dates != null && dates.size() > 0){
                    dates = dates.stream().filter(date -> {
                        if(date.compareTo(today) == 0){
                            return true;
                        }else{
                            return false;
                        }
                    }).collect(Collectors.toList());
                }

                if (lumiereSubscribe.getOrderRule() == 1) {

                    //过滤日期后创建订单， 这里创建的是系统确认的部分订单
                    if(dates != null && dates.size() > 0&&goods != null){
                            if(nowRule.getDaysTimes()  !=  null) {
                                for (int i = 0; i < nowRule.getDaysTimes(); i++) {
                                    autoSubmitOrder(item,goods);
                                }
                            }else{
                                autoSubmitOrder(item,goods);
                            }
                    }

                    //这里生成的数据和由用户确认生成订单相关，往lumiere_subscribe_user_order表中插入状态为未确认的数据
                }else{
                    if(dates != null && dates.size() > 0){
                        //待到用户确认后状态改变，且向订单表中插入数据
                        LumiereSubscribeUserOrder lumiereSubscribeUserOrder = new LumiereSubscribeUserOrder();
                        lumiereSubscribeUserOrder.setOrderId(null);
                        lumiereSubscribeUserOrder.setSubscribeUserId(item.getId());
                        lumiereSubscribeUserOrder.setReceiptTime(LocalDate.now().toString());
                        lumiereSubscribeUserOrder.setStatus(Constants.USER_ORDER_STATUS_NOT);
                        lumiereSubscribeUserOrder.setAddTime(LocalDateTime.now());
                        lumiereSubscribeUserOrder.setUpdateTime(LocalDateTime.now());
                        lumiereSubscribeUserOrder.setDeleted(false);
                        lumiereSubscribeUserOrderService.add(lumiereSubscribeUserOrder);
                    }
                }
                number++;
            }
            noticeHelper.noticeUser(Constants.MSG_TYPE_OTHER,"Subscription confirmation", "You have a subscription to confirm!",item.getUserId(),users);
        });

    }
//查询lumiere_subscribe_user_order表中所有的数据
    //如果定时器扫描时间超过了表中数据的receipt_time配送时间，而且status是未确认
    //就表明订阅已过期，更改数据的状态
//        List<LumiereSubscribeUserOrder> userOrders = lumiereSubscribeUserOrderService.queryNotConfirm();
//        userOrders.forEach(o -> {
//            LocalDate day = LocalDate.parse(o.getReceiptTime());
//            if(today.compareTo(day) > 0){
//                o.setStatus(Constants.USER_ORDER_STATUS_OVER);
//                lumiereSubscribeUserOrderService.update(o);
//            }
//        });
    /**
     * 过期订阅用户订单
     * 订阅订单lumiere_subscribe_user_order表中的数据没有及时确定就已经过期
     */
    @Scheduled(cron = "0 0 23 * * ?")
    public void expiredSubscribeUserOrder(){
        logger.info("订阅订单没有及时确定就已经过期");
        List<LumiereSubscribeUserOrder> orders = lumiereSubscribeUserOrderService.queryAll();
        orders.stream().forEach(order -> {
            LumiereSubscribeUser user = lumiereSubscribeUserService.findById(order.getSubscribeUserId());
            if(user != null && user.getDeliveryEndTime() != null){
//
                LocalDateTime endTime =  LocalDateTime.of(LocalDate.parse(order.getReceiptTime()),user.getDeliveryEndTime());
                if(endTime != null){
                    if(LocalDateTime.now().compareTo(endTime) > 0){
                        order.setStatus((byte) 0);
                        lumiereSubscribeUserOrderService.update(order);
                    }
                }
            }
        });
    }

    /**
     * 订阅订单lumiere_subscribe_user表中的数据判断过期
     */
    @Scheduled(fixedDelay = 5 * 60 * 1000)
    @Transactional
    public void expiredSubscribeUser(){
        List<LumiereSubscribeUser> users =  lumiereSubscribeUserService.queryAllUser();
        LumiereSubscribeUser u = new LumiereSubscribeUser();
        users.stream().forEach(user -> {
            if(user.getEndTime()==null)return;
            if (user.getEndTime().isBefore(LocalDateTime.now())) {
                u.setId(user.getId());
                u.setStatus(0);
                lumiereSubscribeUserService.update(u);
            }
        });
    }

    /**
     * 自动提交订单
     *
     * @param subscribeUser 订阅用户
     * @param goods         货物
     * @return {@link Integer}
     */
    @Transactional
    public Integer autoSubmitOrder(LumiereSubscribeUser subscribeUser, LitemallGoods goods) {
        LitemallOrder order = new LitemallOrder();
//        LitemallOrderGoods orderGoods = new LitemallOrderGoods();

        /**
         * 设置订单项
         */
        order.setShopId(subscribeUser.getShopId());
        Integer addressId = subscribeUser.getAddressId();
        LitemallUser user = userService.findById(subscribeUser.getUserId());
        order =  assembleOrder(order,subscribeUser,user);
        if (addressId != null) {
            LitemallAddress address = litemallAddressService.findById(addressId);
            if (address != null) {
                String addressStr = address.getCountry() + address.getProvince() + address.getCity() + address.getCounty() + address.getAddressDetail();
                order.setAddress(addressStr);
                order.setMobile(address.getTel());
                order.setConsignee(user.getNickname());
            }
        } else {
            order.setConsignee("");
            order.setMobile("");
            order.setAddress("");
        }
        order.setOrderPrice(subscribeUser.getPrice());
        order.setActualPrice(subscribeUser.getPrice());
        order.setFreightPrice(goods.getDistributionFee());
        order.setMadeStatus((byte)0);
        orderService.add(order);
        Integer orderId = order.getId();

        /**
         * 查询订阅配置商品
         */
        LumiereSubscribeGoods lumiereSubscribeGoods = lumiereSubscirbeGoodsService.findBySubIdAndGoodId(subscribeUser.getSubscribeId(), subscribeUser.getGoodsId());
        LitemallGoods litemallGoods = litemallGoodsService.findById(subscribeUser.getGoodsId());

        if(litemallGoods != null){
            /**
             * 设置订单商品项
             */
            LitemallOrderGoods orderGoods = new LitemallOrderGoods();
            orderGoods.setShopId(subscribeUser.getShopId());
            if(lumiereSubscribeGoods.getSpecificationIds() != null){
                orderGoods.setSpecificationIds(lumiereSubscribeGoods.getSpecificationIds());
                /**
                 * 这里应该插入规格名数组，待修改
                 */
                List<String> specs = new ArrayList<>();
                for (int i = 0; i < lumiereSubscribeGoods.getSpecificationIds().length; i++) {
                    LitemallGoodsSpecification byId = litemallGoodsSpecificationService.findById(lumiereSubscribeGoods.getSpecificationIds()[i]);
                    if(byId != null){
                        specs.add(byId.getSpecification());
                    }
                }
                orderGoods.setSpecifications(specs.toArray(new String[lumiereSubscribeGoods.getSpecificationIds().length]));
            }
            orderGoods.setGoodsId(litemallGoods.getId());
            orderGoods.setCategoryId(litemallGoods.getCategoryId());
            orderGoods.setGoodsName(litemallGoods.getName());
            orderGoods.setGoodsSn(litemallGoods.getGoodsSn());
            orderGoods.setOrderId(orderId);
            orderGoods.setProductId(subscribeUser.getGoodsProductId());
            orderGoods.setNumber(subscribeUser.getNumber().shortValue());
            orderGoods.setPicUrl(orderGoods.getPicUrl());
            orderGoods.setSellingPrice(litemallGoods.getRetailPrice());
            orderGoods.setDiscountPrice(orderGoods.getPrice());
            orderGoods.setPrice(subscribeUser.getPrice());
            //orderGoods.setRemark(subscribeUser.getRemark());
            orderGoods.setTaxPrice(subscribeUser.getTaxPrice());
            litemallOrderGoodsService.add(orderGoods);
        }

        /**
         * 设置订单和订阅用户相关关系
         */
        LumiereSubscribeUserOrder lumiereSubscribeUserOrder = new LumiereSubscribeUserOrder();
        lumiereSubscribeUserOrder = assembleUserOrder(lumiereSubscribeUserOrder,orderId,subscribeUser);
        lumiereSubscribeUserOrderService.add(lumiereSubscribeUserOrder);
        return orderId;
    }

    /**
     * 装配顺序
     *
     * @param order         订单
     * @param subscribeUser 订阅用户
     * @param user          用户
     * @return {@link LitemallOrder}
     */
    public LitemallOrder assembleOrder(LitemallOrder order,LumiereSubscribeUser subscribeUser,LitemallUser user){

        //获取支付方式
        LumiereSubscribeUserLog subscribeUserLog = lumiereSubscribeUserLogService.getOne(Wrappers.lambdaQuery(LumiereSubscribeUserLog.class)
                .eq(LumiereSubscribeUserLog::getSubscribeUserId,subscribeUser.getId()));
        /**
         * 因为数据库的类型对不上
         * 付款方式 1:余额 2:礼物卡，3:积分,4：信用卡
         * 支付方式(1:现金支付,2:礼物卡支付,3:Paypal支付,4:余额支付,5:Clover支付,6:积分兑换)
         *
         * pos展示的支付方式与app订阅下单后自动生成的订单支付方式与pos展示不符但app相符
         */
        /*if(order.getOrderSource().equals(Constants.ORDER_SOURCE_POS)){
            switch (subscribeUserLog.getPayType()){
                case 1:{  order.setPayType(Constants.ORDER_PAY_TYPE_CASH);break;}
                case 2:{  order.setPayType(Constants.ORDER_PAY_TYPE_CARD);break;}
                case 3:{  order.setPayType(Constants.ORDER_PAY_TYPE_POINTS);break;}
                case 4:{  order.setPayType(Constants.ORDER_PAY_TYPE_CLOVER);break;}
            }
        }*/
        order.setPayType(subscribeUserLog.getPayType().byteValue());

        order.setPayTime(subscribeUser.getAddTime());
        order.setOrderSource(Constants.ORDER_SOURCE_SUBSCRIBE);
        order.setActualPrice(subscribeUser.getPrice());
        order.setOrderPrice(subscribeUser.getPrice());
        order.setOrderType(subscribeUser.getDeliveryMethod());
        order.setTaxPrice(subscribeUser.getTaxPrice());
        order.setOrderSn(orderService.generateOrderSn(user.getId()));
        order.setReceiptStartTime(LocalDateTime.of(LocalDate.now(), subscribeUser.getDeliveryStartTime()));
        order.setReceiptEndTime(LocalDateTime.of(LocalDate.now(), subscribeUser.getDeliveryEndTime()));
        order.setUserId(user.getId());
        order.setMessage(subscribeUser.getRemark());
        order.setFreightPrice(new BigDecimal(0.00));
        order.setCouponPrice(new BigDecimal(0.00));
        order.setIntegralPrice(new BigDecimal(0.00));
        order.setOrderStatus(Constants.ORDER_STATUS_ONGOING);
        order.setExternalId(subscribeUser.getSubscribeId());
        return  order;
    }

    /**
     * 组装用户订单
     *
     * @param lumiereSubscribeUserOrder 卢米埃订阅用户订单
     * @param orderId                   订单id
     * @param subscribeUser             订阅用户
     * @return {@link LumiereSubscribeUserOrder}
     */
    public LumiereSubscribeUserOrder assembleUserOrder(LumiereSubscribeUserOrder lumiereSubscribeUserOrder,Integer orderId,LumiereSubscribeUser subscribeUser){
        lumiereSubscribeUserOrder.setOrderId(orderId);
        lumiereSubscribeUserOrder.setSubscribeUserId(subscribeUser.getId());
        lumiereSubscribeUserOrder.setReceiptTime(LocalDate.now().toString());
        lumiereSubscribeUserOrder.setStatus(Constants.USER_ORDER_STATUS_CONFIRM);
        lumiereSubscribeUserOrder.setAddTime(LocalDateTime.now());
        lumiereSubscribeUserOrder.setUpdateTime(LocalDateTime.now());
        lumiereSubscribeUserOrder.setDeleted(false);
        return lumiereSubscribeUserOrder;
    }


    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        this.submitSubscribe();
    }
}
